"""
日期时间工具模块
"""
import datetime
from datetime import datetime as dt, timedelta
from dateutil.relativedelta import relativedelta
import random
from typing import List, Tuple
from config.settings import SYSTEM_CONFIG


class DateUtils:
    """日期时间工具类"""
    
    @staticmethod
    def last_day_of_month(any_day: dt) -> dt:
        """获取指定月份的最后一天"""
        next_month = any_day.replace(day=28) + timedelta(days=4)
        return next_month - timedelta(days=next_month.day)
    
    @staticmethod
    def get_date_range(start_date: str, end_date: str) -> List[str]:
        """生成指定日期范围内的日期列表"""
        dates = []
        current_date = dt.strptime(start_date, "%Y-%m-%d")
        end_dt = dt.strptime(end_date, "%Y-%m-%d")
        
        while current_date <= end_dt:
            dates.append(current_date.strftime("%Y-%m-%d"))
            current_date += timedelta(days=1)
        return dates
    
    @staticmethod
    def get_available_dates(custom_date: str = None) -> List[str]:
        """获取可用的日期列表"""
        if custom_date:
            target_date = dt.strptime(custom_date, "%Y-%m-%d")
        else:
            target_date = dt.now()
        
        # 获取下个月的第一天
        next_month = (target_date.replace(day=1) + relativedelta(months=1))
        return [target_date.strftime('%Y-%m-%d')]
    
    @staticmethod
    def get_between_days(begin_date: str, ext_month: int = 1) -> List[str]:
        """获取指定月份范围内的所有日期"""
        date_list = []
        begin_date = dt.strptime(begin_date, "%Y-%m-%d")
        end_date = DateUtils.last_day_of_month(
            dt(dt.now().year, dt.now().month + ext_month, 1)
        )
        
        while begin_date <= end_date:
            date_list.append(begin_date.strftime("%Y-%m-%d"))
            begin_date += timedelta(days=1)
        return date_list
    
    @staticmethod
    def format_datetime(date_str: str) -> str:
        """格式化日期时间字符串"""
        return dt.strptime(date_str, '%Y-%m-%dT%H:%M:%S').strftime('%Y-%m-%d %H:%M')
    
    @staticmethod
    def parse_time_range(time_str: str) -> Tuple[dt, dt]:
        """解析时间范围字符串"""
        start, end = time_str.split('@')
        start_date = dt.strptime(start, '%Y-%m-%dT%H:%M:%S')
        end_date = dt.strptime(end, '%Y-%m-%dT%H:%M:%S')
        return start_date, end_date
    
    @staticmethod
    def filter_by_target_dates(time_list: List[str], target_dates: List[str]) -> List[str]:
        """根据目标日期过滤时间列表"""
        filtered_times = []
        for time_range in time_list:
            start_time, end_time = time_range.split("@")
            start_datetime = dt.fromisoformat(start_time)
            end_datetime = dt.fromisoformat(end_time)
            
            for target_date in target_dates:
                target_dt = dt.strptime(target_date, "%Y-%m-%d").date()
                if start_datetime.date() == target_dt or end_datetime.date() == target_dt:
                    filtered_times.append(time_range)
                    break
        return filtered_times
    
    @staticmethod
    def find_best_time(time_list: List[str]) -> Tuple[str, str]:
        """查找最佳预约时间"""
        # 获取目标日期范围
        target_range = SYSTEM_CONFIG['target_date_range']
        target_dates = DateUtils.get_date_range(
            target_range['start'], 
            target_range['end']
        )
        
        # 过滤时间列表
        filtered_times = DateUtils.filter_by_target_dates(time_list, target_dates)
        
        if not filtered_times:
            return '', ''
        
        # 按时间排序
        sorted_times = sorted(
            [(DateUtils.parse_time_range(s), s) for s in filtered_times],
            key=lambda x: (x[0][0].date(), x[0][0].time())
        )
        
        # 随机选择最后10个时间中的一个
        latest_times = [s for _, s in sorted_times[-10:]]
        if not latest_times:
            return '', ''
            
        selected_time = latest_times[random.randint(0, len(latest_times) - 1)]
        start, end = selected_time.split('@')
        return start, end


# 全局日期工具实例
date_utils = DateUtils()
